<script setup lang="ts">
import { Delete, Search } from '@element-plus/icons-vue';
import { EUserSelectType, ISelectItem } from './types';
import { useUser, useRole, useDept } from './hooks';
import { IRoleVO } from '@/api/admin/role';
import { IUserVO } from '@/api/admin/user';

const model = defineModel<ISelectItem[]>({ default: [] });

const { userList, userLoading, userCurrentPage, userPageSize, keyword, deptId, total, fetchUser, handleSearch, handleClickDept, userScrollbar } =
	useUser();
const { roleLoading, roleList, fetchRole } = useRole();
const { deptLoading, deptList, fetchDept } = useDept();

const visible = ref(false);

const title = computed(() => {
	if (selectType.value === EUserSelectType.USER) {
		return '人员选择';
	} else {
		return '角色选择';
	}
});

const userTree = ref();
const roleTree = ref();
const selectType = ref<EUserSelectType>(EUserSelectType.USER);
const selected = ref<ISelectItem[]>([]);
const selectedIds = computed(() => selected.value.map((item) => item.id));

watch(
	() => model.value,
	(val) => {
		selected.value = val;
	},
	{ immediate: true }
);

function handleClickUser(data: IUserVO, checked: boolean) {
	if (checked) {
		selected.value.push({
			id: data.userId,
			name: data.name,
		});
	} else {
		selected.value = selected.value.filter((item) => item.id !== data.userId);
	}
}
function handleClickRole(data: IRoleVO, checked: boolean) {
	if (checked) {
		selected.value.push({
			id: data.roleId,
			name: data.roleName,
		});
	} else {
		selected.value = selected.value.filter((item) => item.id !== data.roleId);
	}
}

function deleteSelected(index: number) {
	selected.value.splice(index, 1);
	if (selectType.value === EUserSelectType.USER) {
		userTree.value.setCheckedKeys(selectedIds.value);
	} else if (selectType.value === EUserSelectType.ROLE) {
		roleTree.value.setCheckedKeys(selectedIds.value);
	}
}

function open(type: EUserSelectType) {
	selectType.value = type;
	visible.value = true;
	if (type === EUserSelectType.USER) {
		fetchDept();
		fetchUser();
	} else {
		fetchRole();
	}
}

defineExpose({ open });

function save() {
	model.value = selected.value;
	visible.value = false;
}
</script>

<template>
	<el-dialog
		v-model="visible"
		:title="title"
		:width="selectType === EUserSelectType.USER ? 680 : 460"
		destroy-on-close
		append-to-body
		draggable
		@closed="visible = false"
	>
		<template v-if="selectType === EUserSelectType.USER">
			<div class="sc-user-select">
				<div class="sc-user-select__left">
					<div class="sc-user-select__search">
						<el-input v-model="keyword" :prefix-icon="Search" clearable placeholder="搜索成员" @change="handleSearch">
							<template #append>
								<el-button :icon="Search" @click="handleSearch"></el-button>
							</template>
						</el-input>
					</div>
					<div class="sc-user-select__select">
						<div class="sc-user-select__tree" v-loading="deptLoading">
							<el-scrollbar>
								<el-tree
									class="menu"
									ref="groupTree"
									:data="deptList"
									node-key="id"
									:props="{ key: 'id', label: 'name', children: 'children' }"
									highlight-current
									:expand-on-click-node="false"
									:current-node-key="deptId"
									@node-click="handleClickDept"
								/>
							</el-scrollbar>
						</div>
						<div class="sc-user-select__user" v-loading="userLoading">
							<div class="sc-user-select__user__list">
								<el-scrollbar ref="userScrollbar">
									<el-tree
										class="menu"
										ref="userTree"
										:data="userList"
										node-key="id"
										:props="{ key: 'userId', label: 'name', children: 'children' }"
										:default-checked-keys="selectedIds"
										show-checkbox
										check-on-click-node
										@check-change="handleClickUser"
									></el-tree>
								</el-scrollbar>
							</div>
							<footer>
								<el-pagination
									style="margin-top: 0"
									background
									layout="prev,next"
									small
									:total="total"
									:page-size="userPageSize"
									v-model:currentPage="userCurrentPage"
									@current-change="fetchUser"
								></el-pagination>
							</footer>
						</div>
					</div>
				</div>
				<div class="sc-user-select__toicon">
					<el-icon>
						<ArrowRight />
					</el-icon>
				</div>
				<div class="sc-user-select__selected">
					<header>已选 ({{ selected.length }})</header>
					<ul>
						<el-scrollbar>
							<li v-for="(item, index) in selected" :key="item.id">
								<span class="name">
									<el-avatar size="small">{{ item.name.substring(0, 1) }}</el-avatar>
									<label>{{ item.name }}</label>
								</span>
								<span class="delete">
									<el-button type="danger" :icon="Delete" circle size="small" @click="deleteSelected(index)"></el-button>
								</span>
							</li>
						</el-scrollbar>
					</ul>
				</div>
			</div>
		</template>

		<template v-if="selectType === EUserSelectType.ROLE">
			<div class="sc-user-select sc-user-select-role">
				<div class="sc-user-select__left">
					<div class="sc-user-select__select">
						<div class="sc-user-select__tree" v-loading="roleLoading">
							<el-scrollbar>
								<el-tree
									class="menu"
									ref="roleTree"
									:data="roleList"
									node-key="roleId"
									:props="{ key: 'roleId', label: 'roleName' }"
									show-checkbox
									check-strictly
									check-on-click-node
									:expand-on-click-node="false"
									:default-checked-keys="selectedIds"
									@check-change="handleClickRole"
								/>
							</el-scrollbar>
						</div>
					</div>
				</div>
				<div class="sc-user-select__toicon">
					<el-icon>
						<ArrowRight />
					</el-icon>
				</div>
				<div class="sc-user-select__selected">
					<header>已选 ({{ selected.length }})</header>
					<ul>
						<el-scrollbar>
							<li v-for="(item, index) in selected" :key="item.id">
								<span class="name">
									<label>{{ item.name }}</label>
								</span>
								<span class="delete">
									<el-button type="danger" :icon="Delete" circle size="small" @click="deleteSelected(index)"></el-button>
								</span>
							</li>
						</el-scrollbar>
					</ul>
				</div>
			</div>
		</template>

		<template #footer>
			<el-button @click="visible = false">取 消</el-button>
			<el-button type="primary" @click="save">确 认</el-button>
		</template>
	</el-dialog>
</template>

<style scoped>
.sc-user-select {
	display: flex;
}

.sc-user-select__left {
	width: 400px;
}

.sc-user-select__right {
	flex: 1;
}

.sc-user-select__search {
	padding-bottom: 10px;
}

.sc-user-select__select {
	display: flex;
	border: 1px solid var(--el-border-color-light);
	background: var(--el-color-white);
}

.sc-user-select__tree {
	width: 200px;
	height: 300px;
	border-right: 1px solid var(--el-border-color-light);
}

.sc-user-select__user {
	width: 200px;
	height: 300px;
	display: flex;
	flex-direction: column;
}

.sc-user-select__user__list {
	flex: 1;
	overflow: auto;
}

.sc-user-select__user footer {
	height: 36px;
	padding-top: 5px;
	border-top: 1px solid var(--el-border-color-light);
}

.sc-user-select__toicon {
	display: flex;
	justify-content: center;
	align-items: center;
	margin: 0 10px;
}

.sc-user-select__toicon i {
	display: flex;
	justify-content: center;
	align-items: center;
	background: #ccc;
	width: 20px;
	height: 20px;
	text-align: center;
	line-height: 20px;
	border-radius: 50%;
	color: #fff;
}

.sc-user-select__selected {
	height: 345px;
	width: 200px;
	border: 1px solid var(--el-border-color-light);
	background: var(--el-color-white);
}

.sc-user-select__selected header {
	height: 43px;
	line-height: 43px;
	border-bottom: 1px solid var(--el-border-color-light);
	padding: 0 15px;
	font-size: 12px;
}

.sc-user-select__selected ul {
	height: 300px;
	overflow: auto;
}

.sc-user-select__selected li {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 5px 5px 5px 15px;
	height: 38px;
}

.sc-user-select__selected li .name {
	display: flex;
	align-items: center;
}

.sc-user-select__selected li .name .el-avatar {
	background: #409eff;
	margin-right: 10px;
}

.sc-user-select__selected li .delete {
	display: none;
}

.sc-user-select__selected li:hover {
	background: var(--el-color-primary-light-9);
}

.sc-user-select__selected li:hover .delete {
	display: inline-block;
}

.sc-user-select-role .sc-user-select__left {
	width: 200px;
}

.sc-user-select-role .sc-user-select__tree {
	border: none;
	height: 343px;
}

[data-theme='dark'] .sc-user-select__selected li:hover {
	background: rgba(0, 0, 0, 0.2);
}

[data-theme='dark'] .sc-user-select__toicon i {
	background: #383838;
}
</style>
